import sys

from PyQt5.QtWidgets import QWidget, QLabel, QGridLayout, QApplication, \
    QStackedWidget, QPushButton, QHBoxLayout, QVBoxLayout, QScrollArea, \
    QLineEdit, QFileDialog, QGraphicsDropShadowEffect
from PyQt5.QtGui import QPixmap, QFont, QIntValidator, QDoubleValidator, QCursor
from PyQt5.QtCore import Qt, pyqtSignal
from PyQt5.QtCore import QObject, QUrl, QByteArray
from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest
from Dialog import FileDialog, WarningMessageBox
from base64 import b64encode, b64decode
from shopInterfaceTools import slideButton, picEditableLabel, hClsWidget
import requests
import sys
import copy
import cv2
import numpy as np
import time
import shutil
import os
from handler.goodsHandle import goodsHandle

goodsList = [{
        "goods_id": "1",
        "goods_title": "土鸡蛋20枚装",
        "good_type": 1,
        "imageContent": [
            "https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=1887942828,972848009&fm=26&gp=0.jpg",
            "https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1956320807,1368482897&fm=26&gp=0.jpg",
            "https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=2192842524,640789728&fm=26&gp=0.jpg",
            "https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2167237248,612060343&fm=26&gp=0.jpg",
            "https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1925142767,3806138753&fm=26&gp=0.jpg",
        ],
        "status": 0,
        "update_time": None,
        "imagesSlider": [
            "https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=1887942828,972848009&fm=26&gp=0.jpg",
            "https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1956320807,1368482897&fm=26&gp=0.jpg",
            "https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=2192842524,640789728&fm=26&gp=0.jpg", 
            ],
        "defaultImgIndex": 0, 
        "price": 27, 
        "sales": 327, 
        "stock": 2179,
        "needJoin": 20,  # 需要拼单的数量
        "buy_type": 1,  # 1正常，2团购
        "good_type1": 1,  # 商品类型一级分类
        "good_type2": 1,   # 商品类型二级分类
        "baseCount":50,   # 分销基本数量
        "discount":0.5,  # 折扣
    },
{
        "goods_id": "1",
        "goods_title": "土鸡蛋20枚装",
        "good_type": 1,
        "imageContent": [
            "https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=1887942828,972848009&fm=26&gp=0.jpg",
            "https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1956320807,1368482897&fm=26&gp=0.jpg",
            "https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=2192842524,640789728&fm=26&gp=0.jpg",
            "https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2167237248,612060343&fm=26&gp=0.jpg",
            "https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1925142767,3806138753&fm=26&gp=0.jpg",
        ],
        "status": 0,
        "update_time": None,
        "imagesSlider": [
            "https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=1887942828,972848009&fm=26&gp=0.jpg",
            "https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1956320807,1368482897&fm=26&gp=0.jpg",
            "https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=2192842524,640789728&fm=26&gp=0.jpg",
            ],
        "defaultImgIndex": 1,
        "price": 27,
        "sales": 327,
        "stock": 2179,
        "needJoin": 30,  # 需要拼单的数量
        "buy_type": 1,  # 1正常，2团购
        "good_type1": 2,  # 商品类型一级分类
        "good_type2": 1,   # 商品类型二级分类
        "baseCount":60,   # 分销基本数量
        "discount":0.9,  # 折扣
    },
]

initGoodsItemData = {
        "goods_id": 0,
        "goods_title": "",
        "goods_content": "",
        "imageContent": [
            "请点击插入图片",
            "请点击插入图片",
            "请点击插入图片",
            "请点击插入图片",
            "请点击插入图片",
        ],
        "status": 0,
        "imagesSlider": [
            "请点击插入图片",
            "请点击插入图片",
            "请点击插入图片",
            ],
        "defaultImgIndex": 0,
        "price": 0,
        "sales": 0,
        "stock": 0,
        "needJoin": 0,  # 需要拼单的数量
        "buy_type": 1,  # 1正常，2团购
        "goods_type1": 1,  # 商品类型一级分类
        "goods_type2": 1,   # 商品类型二级分类
        "baseCount": 0,   # 分销基本数量
        "discount": 0,  # 折扣
        "remark": "",
        "vip_1_discount": 0,  # 会员
        "vip_2_discount": 0,  # 银卡优惠
        "vip_3_discount": 0,  # 金卡优惠
        "vip_4_discount": 0,  # 钻石卡优惠
        "delivery_fee": 0  # 邮费
    }

classData = [
    {
        "goods_type1": "肉类",
        "goods_type2": "鸡肉",
        "id": 1,
        "pid": 1,
    },
    {
        "goods_type1": "肉类",
        "goods_type2": "鸭肉",
        "id": 1,
        "pid": 2,
    },
    {
        "goods_type1": "肉类",
        "goods_type2": "羊肉",
        "id": 1,
        "pid": 3,
    },
    {
        "goods_type1": "肉类",
        "goods_type2": "鸵鸟肉",
        "id": 1,
        "pid": 4,
    },
    {
        "goods_type1": "蔬菜类",
        "goods_type2": "大白菜",
        "id": 2,
        "pid": 1,
    },
    {
        "goods_type1": "蔬菜类",
        "goods_type2": "空心菜",
        "id": 2,
        "pid": 2,
    },
    {
        "goods_type1": "蔬菜类",
        "goods_type2": "辣椒",
        "id": 2,
        "pid": 3,
    },
    {
        "goods_type1": "奶类",
        "goods_type2": "牛奶",
        "id": 3,
        "pid": 1,
    },
    {
        "goods_type1": "奶类",
        "goods_type2": "羊奶",
        "id": 3,
        "pid": 2,
    },
    {
        "goods_type1": "蛋类",
        "goods_type2": "鸡蛋",
        "id": 4,
        "pid": 1,
    },
    {
        "goods_type1": "蛋类",
        "goods_type2": "鸭蛋",
        "id": 4,
        "pid": 2,
    },
    {
        "goods_type1": "蛋类",
        "goods_type2": "鸵鸟蛋",
        "id": 4,
        "pid": 3,
    }
]

class goodsItem(QWidget):
    goodsItemClicked = pyqtSignal(dict)

    def __init__(self, parent=None):
        super(goodsItem, self).__init__(parent)
        # 布局
        self.setFixedSize(250, 300)
        layout = QGridLayout()
        self._data = None
        self._dataIndex = None
        self._picLb = QLabel()
        self._picLb.setFixedSize(234, 220)
        font = QFont()
        font.setPixelSize(30)
        font.setFamily("SimSun")
        self._picLb.setStyleSheet("background-color:gray")
        self._picLb.setFont(font)
        self._picLb.setAlignment(Qt.AlignCenter)
        self._descLb = QLabel()

        self._priceLb = QLabel()
        self._salesLb = QLabel()
        self._initLayout(layout)
        self.setObjectName("mainWidget")
        self.setAttribute(Qt.WA_StyledBackground, True)
        #self.setWindowFlags(Qt.FramelessWindowHint)
        self.m_netAccessManager = QNetworkAccessManager(self)
        self.m_netReply = None

    def q_request(self, url):
        if url.startswith("http"):
            if self.m_netReply is not None:
                self.m_netReply.disconnect()

            req = QNetworkRequest(QUrl(url))
            self.m_netReply = self.m_netAccessManager.get(req)

            self.m_netReply.finished.connect(self.readData)

        else:
            self._displayimg(url, self._picLb)

    def readData(self):
        recvData = self.m_netReply.readAll()
        pix = QPixmap()
        pix.loadFromData(recvData)
        pix = pix.scaled(self._picLb.width(), self._picLb.height())
        self._picLb.setPixmap(pix)
        image_byte = b64encode(recvData)
        base64_string = image_byte.decode('utf-8')
        self._data["imagesSlider"][0] = base64_string

    def _initLayout(self, layout):
        layout.addWidget(self._picLb, 0, 0, 3, 2)
        layout.addWidget(self._descLb, 3, 0, 1, 2)
        layout.addWidget(self._priceLb, 4, 0, 1, 1)
        layout.addWidget(self._salesLb, 4, 1, 1, 1)
        layout.setContentsMargins(8, 8, 8, 8)
        self.setLayout(layout)

    def _displayimg(self, url, label):
        pix = QPixmap()
        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
        if url.startswith("http"):
            start = time.time()
            i = 0
            QApplication.processEvents()
            while i < 1000:
                try:
                    response = requests.get(url, timeout=(2, 0.5))
                    break
                except requests.exceptions.RequestException as e:
                    print(e)
                    i += 1
                    if i == 999:
                        return

            print('time', time.time() - start)
            pix.loadFromData(response.content)
            pix = pix.scaled(label.width(), label.height())
            label.setStyleSheet("border:none")
            label.setPixmap(pix)
            image_byte = b64encode(response.content)
            base64_string = image_byte.decode('utf-8')
            QApplication.restoreOverrideCursor()
            return base64_string
        elif url == "请点击插入图片":
            label.setText(url)
            label.setStyleSheet("background-color:gray;border: 1px solid black;")
        else:
            url = url.encode("utf-8")
            image_data = b64decode(url)
            pix.loadFromData(image_data)
            pix = pix.scaled(label.width(), label.height())
            label.setStyleSheet("border:none")
            label.setPixmap(pix)
        QApplication.restoreOverrideCursor()
        return None

    def updateData(self, data):
        self._data = data
        # 显示图片
        url = data["imagesSlider"][data["defaultImgIndex"]]

        # 显示标题
        font = QFont()
        font.setBold(True)
        font.setFamily("黑体")
        self._descLb.setFont(font)
        self._descLb.setText(data["goods_title"])

        # 显示价格
        self._priceLb.setStyleSheet("color: red")
        font.setPixelSize(20)
        self._priceLb.setFont(font)
        self._priceLb.setText("¥" + str(data["price"]))

        # 显示销量和状态
        font.setPixelSize(13)
        font.setBold(False)
        font.setFamily("SimSun")
        font.setItalic(True)
        self._salesLb.setFont(font)
        text = "已售" + str(data["sales"])
        if not data["status"]:
            text += "   已上架"
        else:
            text += "   已下架"
        self._salesLb.setText(text)
        # ret = self._displayimg(url, self._picLb)
        # if ret is not None:
        #     data["imagesSlider"][data["defaultImgIndex"]] = ret
        self.q_request(url)

    def setDataIndex(self, index):
        self._dataIndex = index

    def dataIndex(self):
        return self._dataIndex

    def data(self):
        return self._data

    def mouseReleaseEvent(self, event):
        super(goodsItem, self).mouseReleaseEvent(event)
        if self._data is not None:
            self.goodsItemClicked.emit(self._data)


class goodsMessageEditWidget(QScrollArea):
    cancelBtnClicked = pyqtSignal()
    goodsStatus = pyqtSignal(bool)
    goodsDelete = pyqtSignal(list)

    def __init__(self, parent=None):
        super(goodsMessageEditWidget, self).__init__(parent)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)

        self._mainWidget = QWidget(self)
        # 存储编辑过的信息
        self._data = None

        # 存放正在被编辑的商品
        self._goodsItem = None

        # 当前被按下的轮播图按键
        self._currentSlideBtn = None

        # 当前编辑商品的分类
        self._currentClass = None

        # 判断是否为添加商品初始化界面
        self._isinit = False

        # 轮播图界面
        self._slideShowWidget = QWidget()
        self._slideBtnWidget = QWidget()
        self._slideShowBtn = list()
        for index in range(3):
            self._slideShowBtn.append(slideButton(index))
            if index == 0:
                self._currentSlideBtn = self._slideShowBtn[index]
            self._slideShowBtn[index].currentIndex.connect(self._updateSlidePic)
        self._slideShowLb = picEditableLabel()
        self._slideShowLb.setFixedSize(500, 400)
        self._initslideWdiget()

        # 上传轮播图
        self._slideShowLb.picLbClicked.connect(self._uplaodPic)

        # 信息编辑界面、上下架控制
        self._msgWidget = QWidget()
        self._titleLineEdit = QLineEdit()
        self._priceLb = QLabel()
        self._priceLb.setObjectName("msgEditWidgetLb")
        self._priceLineEdit = QLineEdit()
        self._salesLb = QLabel()
        self._salesLb.setObjectName("msgEditWidgetLb")
        self._stockLb = QLabel()
        self._stockLb.setObjectName("msgEditWidgetLb")
        self._stockLineEdit = QLineEdit()
        self._needJoinLb = QLabel()
        self._needJoinLb.setObjectName("msgEditWidgetLb")
        self._needJoinLineEdit = QLineEdit()
        self._baseCountLb = QLabel()
        self._baseCountLb.setObjectName("msgEditWidgetLb")
        self._baseCountLineEdit = QLineEdit()
        self._discountLb = QLabel()
        self._discountLb.setObjectName("msgEditWidgetLb")
        self._discountLineEdit = QLineEdit()

        # 邮费
        self._delivery_fee_Lb = QLabel()
        self._delivery_fee_Lb.setObjectName("msgEditWidgetLb")
        self._delivery_fee_LineEdit = QLineEdit()

        # 会员卡优惠
        self._vip_1_discountLb = QLabel()
        self._vip_1_discountLb.setObjectName("msgEditWidgetLb")
        self._vip_1_discountLineEdit = QLineEdit()

        # 银卡
        self._vip_2_discountLb = QLabel()
        self._vip_2_discountLb.setObjectName("msgEditWidgetLb")
        self._vip_2_discountLineEdit = QLineEdit()

        # 金卡
        self._vip_3_discountLb = QLabel()
        self._vip_3_discountLb.setObjectName("msgEditWidgetLb")
        self._vip_3_discountLineEdit = QLineEdit()

        # 钻石卡
        self._vip_4_discountLb = QLabel()
        self._vip_4_discountLb.setObjectName("msgEditWidgetLb")
        self._vip_4_discountLineEdit = QLineEdit()

        # 上下架控制
        self._cancelBtn = QPushButton()
        self._submitBtn = QPushButton()
        self._unShelveBtn = QPushButton()
        self._cancelBtn.clicked.connect(self._onCancel)
        self._submitBtn.clicked.connect(self._onSubmit)
        self._unShelveBtn.clicked.connect(self._onUnShelve)
        # self._goodsTypeLb = QLabel()
        # self._goodsTypeLineEdit = QLineEdit()

        # 删除商品
        self._deleteBtn = QPushButton()
        self._deleteBtn.clicked.connect(self._onDelete)

        self._initmsgWidget()

        # 图片详情
        self._detailsWidget = QWidget()
        self._detailsWidget.setMinimumSize(1300, 3000)
        self._detailsPicLb = list()
        for index in range(5):
            self._detailsPicLb.append(picEditableLabel(index))
            self._detailsPicLb[index].picLbClicked.connect(self._uplaodPic)
        glayout = QGridLayout()
        for each in range(self._detailsPicLb.__len__()):
            self._detailsPicLb[each].setMinimumSize(1000, 600)
            glayout.addWidget(self._detailsPicLb[each], each, 0, Qt.AlignCenter)
        glayout.setSpacing(0)
        self._detailsWidget.setLayout(glayout)

        # 整体界面布局
        glayout = QGridLayout()
        glayout.addWidget(self._slideShowWidget, 0, 0, 1, 1, Qt.AlignCenter)
        glayout.addWidget(self._msgWidget, 0, 1, 1, 1, Qt.AlignCenter | Qt.AlignLeft)
        glayout.addWidget(self._detailsWidget, 1, 0, 1, 2)
        glayout.setColumnStretch(0, 1)
        glayout.setColumnStretch(1, 1)
        glayout.setContentsMargins(0, 20, 0, 0)
        self._mainWidget.setLayout(glayout)
        #self.setStyleSheet("background-color:white")
        self.setWidget(self._mainWidget)
        self.setMinimumWidth(self.width())
        #self._deleteBtn.hide()

    def _displayimg(self, url, label):
        pix = QPixmap()
        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
        if url.startswith("http"):
            QApplication.processEvents()
            response = requests.get(url)
            pix.loadFromData(response.content)
            pix = pix.scaled(label.width(), label.height())
            label.setStyleSheet("border:none")
            label.setPixmap(pix)
            image_byte = b64encode(response.content)
            base64_string = image_byte.decode('utf-8')
            QApplication.restoreOverrideCursor()
            return base64_string
        elif url == "请点击插入图片":
            label.setText(url)
            label.setStyleSheet("background-color:gray;border: 1px solid black;")
        else:
            url = url.encode("utf-8")
            image_data = b64decode(url)
            pix.loadFromData(image_data)
            pix = pix.scaled(label.width(), label.height())
            label.setStyleSheet("border:none")
            label.setPixmap(pix)
        QApplication.restoreOverrideCursor()
        return None

    def _initslideWdiget(self):
        vlayout = QVBoxLayout()
        hlayout = QHBoxLayout()

        hlayout.addStretch()
        for index in range(3):
            hlayout.addWidget(self._slideShowBtn[index])
        self._slideBtnWidget.setLayout(hlayout)

        vlayout.addWidget(self._slideShowLb)
        vlayout.addWidget(self._slideBtnWidget)

        self._slideShowWidget.setLayout(vlayout)

    def _initmsgWidget(self):
        # 编辑标题
        font = QFont()
        font.setBold(True)
        font.setFamily("SimSun")
        font.setPixelSize(16)
        self._titleLineEdit.setFont(font)

        # 编辑价格
        self._priceLb.setStyleSheet("color: red")
        font.setPixelSize(23)
        self._priceLb.setFont(font)
        self._priceLb.setText("¥")
        self._priceLineEdit.setStyleSheet("color: red")
        self._priceLineEdit.setFont(font)
        self._priceLineEdit.setValidator(QDoubleValidator(0, 100000000, 2))

        # 显示销量
        self._salesLb.setFont(font)
        self._salesLb.setText("已售:230")

        # 编辑库存
        #self._stockLb.setFont(font)
        self._stockLineEdit.setFont(font)
        self._stockLb.setText("库存")
        self._stockLineEdit.setValidator(QIntValidator(0, 1000000000))

        self._needJoinLb.setText("需要拼单数量")
        self._needJoinLineEdit.setValidator(QIntValidator(0, 1000000000))
        self._baseCountLb.setText("分销基本数量")
        self._baseCountLineEdit.setValidator(QIntValidator(0, 1000000000))
        self._discountLb.setText("折扣")
        dv = QDoubleValidator(0, 9, 2, self)
        dv.setNotation(QDoubleValidator.StandardNotation)
        self._discountLineEdit.setValidator(dv)

        # 邮费
        self._delivery_fee_Lb.setText("运费")
        self._delivery_fee_LineEdit.setValidator(QDoubleValidator(0, 1000000000, 2, self))

        # 会员卡优惠
        self._vip_1_discountLb.setText("会员卡优惠")
        self._vip_1_discountLineEdit.setValidator(QIntValidator(0, 50))

        # 银卡
        self._vip_2_discountLb.setText("银卡优惠")
        self._vip_2_discountLineEdit.setValidator(QIntValidator(0, 50))

        # 金卡
        self._vip_3_discountLb.setText("金卡优惠")
        self._vip_3_discountLineEdit.setValidator(QIntValidator(0, 50))

        # 钻石卡
        self._vip_4_discountLb.setText("钻石卡优惠")
        self._vip_4_discountLineEdit.setValidator(QIntValidator(0, 50))

        # 上下架、取消、删除按键
        self._cancelBtn.setText("取消")
        self._submitBtn.setText("上架")
        self._unShelveBtn.setText("下架")
        self._deleteBtn.setText("删除")
        self._cancelBtn.setProperty("class", "editWidgetBtn")
        self._submitBtn.setProperty("class", "editWidgetBtn")
        self._unShelveBtn.setProperty("class", "editWidgetBtn")
        self._deleteBtn.setProperty("class", "editWidgetBtn")

        # 布局
        glayout = QGridLayout()
        glayout.addWidget(self._titleLineEdit, 0, 0, 1, 2, Qt.AlignBottom)
        glayout.addWidget(self._submitBtn, 0, 2, 1, 1, Qt.AlignRight | Qt.AlignTop)
        glayout.addWidget(self._priceLb, 1, 0, 1, 1, Qt.AlignBottom)
        glayout.addWidget(self._priceLineEdit, 1, 1, 1, 1, Qt.AlignBottom)
        glayout.addWidget(self._unShelveBtn, 1, 2, 1, 1, Qt.AlignRight | Qt.AlignTop)
        glayout.addWidget(self._salesLb, 2, 0, 1, 2, Qt.AlignBottom)
        glayout.addWidget(self._deleteBtn, 2, 2, 1, 1, Qt.AlignRight | Qt.AlignTop)
        glayout.addWidget(self._stockLb, 3, 0, 1, 1, Qt.AlignBottom)
        glayout.addWidget(self._stockLineEdit, 3, 1, 1, 1, Qt.AlignBottom)
        glayout.addWidget(self._cancelBtn, 3, 2, 1, 1, Qt.AlignRight | Qt.AlignTop)
        glayout.addWidget(self._needJoinLb, 4, 0, 1, 1, Qt.AlignBottom)
        glayout.addWidget(self._needJoinLineEdit, 4, 1, 1, 1, Qt.AlignBottom)
        glayout.addWidget(self._baseCountLb, 5, 0, 1, 1, Qt.AlignBottom)
        glayout.addWidget(self._baseCountLineEdit, 5, 1, 1, 1, Qt.AlignBottom)
        glayout.addWidget(self._discountLb, 6, 0, 1, 1, Qt.AlignBottom)
        glayout.addWidget(self._discountLineEdit, 6, 1, 1, 1, Qt.AlignBottom)

        glayout.addWidget(self._delivery_fee_Lb, 7, 0, 1, 1, Qt.AlignBottom)
        glayout.addWidget(self._delivery_fee_LineEdit, 7, 1, 1, 1, Qt.AlignBottom)
        glayout.addWidget(self._vip_1_discountLb, 8, 0, 1, 1, Qt.AlignBottom)
        glayout.addWidget(self._vip_1_discountLineEdit, 8, 1, 1, 1, Qt.AlignBottom)
        glayout.addWidget(self._vip_2_discountLb, 9, 0, 1, 1, Qt.AlignBottom)
        glayout.addWidget(self._vip_2_discountLineEdit, 9, 1, 1, 1, Qt.AlignBottom)
        glayout.addWidget(self._vip_3_discountLb, 10, 0, 1, 1, Qt.AlignBottom)
        glayout.addWidget(self._vip_3_discountLineEdit, 10, 1, 1, 1, Qt.AlignBottom)
        glayout.addWidget(self._vip_4_discountLb, 11, 0, 1, 1, Qt.AlignBottom)
        glayout.addWidget(self._vip_4_discountLineEdit, 11, 1, 1, 1, Qt.AlignBottom)
        glayout.setSpacing(20)
        glayout.setContentsMargins(0, 0, 0, 0)
        self._msgWidget.setLayout(glayout)

    # 按键切换显示图片
    def _updateSlidePic(self, index):
        self._currentSlideBtn = self.sender()
        ret = self._displayimg(self._data["imagesSlider"][index], self._slideShowLb)
        if ret is not None:
            self._data["imagesSlider"][index] = ret

    # 上传图片时显示图片
    def _updateSlidePicFromFile(self, index):
        ret = self._displayimg(self._data["imagesSlider"][index], self._slideShowLb)
        if ret is not None:
            self._data["imagesSlider"][index] = ret

    def _updateDedetailsPic(self, label):
        ret = self._displayimg(self._data["imageContent"][label.index()], label)
        if ret is not None:
            self._data["imageContent"][label.index()] = ret

    def _onCancel(self):
        self.cancelBtnClicked.emit()

    def _onSubmit(self):
        self.goodsStatus.emit(True)

    def _onUnShelve(self):
        self.goodsStatus.emit(False)

    def _onDelete(self):
        if self._isinit:
            self.goodsDelete.emit([None, ])
        else:
            self.goodsDelete.emit([self._goodsItem, ])

    # 上传轮播图或图片详情图片
    def _uplaodPic(self, mode):
        fd = FileDialog(QFileDialog.AcceptOpen, "选择图片")
        path = fd.getSelectFilePath()
        if path is not None:
            img = cv2.imdecode(np.fromfile(path, dtype=np.uint8), -1)

            # width = img.shape[1]
            # height = img.shape[0]
            # width_new = 500
            # height_new = 400
            # # 判断图片的长宽比率
            # if width / height >= width_new / height_new:
            #     img_new = cv2.resize(img, (width_new, int(height * width_new / width)))
            # else:
            #     img_new = cv2.resize(img, (int(width * height_new / height), height_new))

            img_new = img

            #img_new = cv2.resize(img, (900, 900))
            cv2.imwrite('./temp/temp.jpg', img_new)
            with open('./temp/temp.jpg', "rb") as file:
                image_byte = b64encode(file.read())
            base64_string = image_byte.decode('utf-8')
            if mode == -1:
                index = self._currentSlideBtn.index()
                self._data["imagesSlider"][index] = base64_string
                self._updateSlidePicFromFile(index)
            else:
                self._data["imageContent"][mode] = base64_string
                self._updateDedetailsPic(self._detailsPicLb[mode])

    def _normalMode(self):
        self._needJoinLb.hide()
        self._needJoinLineEdit.hide()
        self._baseCountLb.hide()
        self._baseCountLineEdit.hide()
        self._discountLb.hide()
        self._discountLineEdit.hide()

        self._vip_1_discountLb.show()
        self._vip_1_discountLineEdit.show()
        self._vip_2_discountLb.show()
        self._vip_2_discountLineEdit.show()
        self._vip_3_discountLb.show()
        self._vip_3_discountLineEdit.show()
        self._vip_4_discountLb.show()
        self._vip_4_discountLineEdit.show()

    def _groupMode(self):
        self._needJoinLb.show()
        self._needJoinLineEdit.show()
        self._baseCountLb.hide()
        self._baseCountLineEdit.hide()
        self._discountLb.hide()
        self._discountLineEdit.hide()

        self._vip_1_discountLb.hide()
        self._vip_1_discountLineEdit.hide()
        self._vip_2_discountLb.hide()
        self._vip_2_discountLineEdit.hide()
        self._vip_3_discountLb.hide()
        self._vip_3_discountLineEdit.hide()
        self._vip_4_discountLb.hide()
        self._vip_4_discountLineEdit.hide()

    def _distributionMode(self):
        self._needJoinLb.hide()
        self._needJoinLineEdit.hide()
        self._baseCountLb.show()
        self._baseCountLineEdit.show()
        self._discountLb.show()
        self._discountLineEdit.show()

        self._vip_1_discountLb.hide()
        self._vip_1_discountLineEdit.hide()
        self._vip_2_discountLb.hide()
        self._vip_2_discountLineEdit.hide()
        self._vip_3_discountLb.hide()
        self._vip_3_discountLineEdit.hide()
        self._vip_4_discountLb.hide()
        self._vip_4_discountLineEdit.hide()

    def getDictData(self, data, key):
        return data.get(key) if (data.get(key) is not None) else 0

    def updateData(self, data, isinit=False):
        self._data = data
        self._isinit = isinit
        if not isinit:
            self._goodsItem = self.sender()
            self._unShelveBtn.show()
        else:
            self._goodsItem = None
            self._unShelveBtn.hide()

        self._titleLineEdit.setText(data["goods_title"])
        self._priceLineEdit.setText(str(data["price"]))
        self._salesLb.setText("已售:" + str(data["sales"]))
        self._stockLineEdit.setText(str(data["stock"]))
        self._delivery_fee_LineEdit.setText(str(data["delivery_fee"]))
        self._displayimg(data["imagesSlider"][data["defaultImgIndex"]], self._slideShowLb)
        for each in range(data["imageContent"].__len__()):
            ret = self._displayimg(data["imageContent"][self._detailsPicLb[each].index()], self._detailsPicLb[each])
            if ret is not None:
                data["imageContent"][self._detailsPicLb[each].index()] = ret

        classname = list(self._currentClass.keys())[0]
        if classname == "普通":
            self._normalMode()
            self._vip_1_discountLineEdit.setText(str(self.getDictData(data, "vip_1_discount")))
            self._vip_2_discountLineEdit.setText(str(self.getDictData(data, "vip_2_discount")))
            self._vip_3_discountLineEdit.setText(str(self.getDictData(data, "vip_3_discount")))
            self._vip_4_discountLineEdit.setText(str(self.getDictData(data, "vip_4_discount")))
        elif classname == "拼团":
            self._groupMode()
            self._needJoinLineEdit.setText(str(data["needJoin"]))
            self._discountLineEdit.setText(str(data["discount"]))
        elif classname == "分销":
            self._distributionMode()
            self._baseCountLineEdit.setText(str(data["baseCount"]))
            self._discountLineEdit.setText(str(data["discount"]))

    # 获取被编辑的数据
    def getEditedData(self):
        if self._data is not None:
            self._data["goods_title"] = self._titleLineEdit.text()
            self._data["price"] = float(self._priceLineEdit.text())
            self._data["stock"] = int(self._stockLineEdit.text())
            self._data["delivery_fee"] = float(self._delivery_fee_LineEdit.text())

            classname = list(self._currentClass.keys())[0]
            if classname == "普通":
                self._data["vip_1_discount"] = int(self._vip_1_discountLineEdit.text())
                self._data["vip_2_discount"] = int(self._vip_2_discountLineEdit.text())
                self._data["vip_3_discount"] = int(self._vip_3_discountLineEdit.text())
                self._data["vip_4_discount"] = int(self._vip_4_discountLineEdit.text())
            elif classname == "拼团":
                self._data["needJoin"] = int(self._needJoinLineEdit.text())
                self._data["discount"] = float(self._discountLineEdit.text())
            elif classname == "分销":
                self._data["baseCount"] = int(self._baseCountLineEdit.text())
                self._data["discount"] = float(self._discountLineEdit.text())

            values = list(self._currentClass.values())
            self._data["buy_type"] = values[0]
            self._data["goods_type1"] = values[1]
            self._data["goods_type2"] = values[2]

            return self._data

        return None

    # 更新对应的商品信息
    def updateGoodsItem(self):
        if not self._isinit:
            self._goodsItem.updateData(self._data)
            return None
        else:
            ret = goodsItem()
            ret.updateData(self._data)

            return ret

    def currentEditItem(self):
        return self._goodsItem

    # 修改上下架信息并返回
    def setSalesStatus(self, status):
        if status:
            self._data["status"] = 0
            return 0
        else:
            self._data["status"] = 1
            return 1

    def setClass(self, classdict):
        self._currentClass = classdict

class classifyWidget(QWidget):
    allSelected = pyqtSignal(list)
    sg_onRmCls = pyqtSignal(list)

    def __init__(self, parent=None):
        super(classifyWidget, self).__init__(parent=parent)
        self._hClsWidgetList = list()
        self._type1map = dict()
        self._type2map = dict()
        self._typeWidgetmap = dict()
        self._rowDatamap = dict()
        self._handle = goodsHandle()
        self._layout = QVBoxLayout()
        self.setLayout(self._layout)
        self.setAttribute(Qt.WA_StyledBackground, True)
        self.setObjectName("classifyWidget")
        self.addRow(["普通", "拼团"])
        self._hClsWidgetList[0].addRmDisable()

    def show_init(self, data):
        self.getData(data)
        self.addRow(list(self._type1map.keys()))
        self._hClsWidgetList[1].addRmDisable()
        self.addRow([])

    def addRow(self, initdata=list()):
        ret = hClsWidget(default_cls=initdata)
        ret.rowSelected.connect(self._onSelected)
        ret.clsAdd.connect(self.addCls)
        ret.clsRm.connect(self.onRmCls)
        self._hClsWidgetList.append(ret)
        self._layout.addWidget(ret)

    def rmRow(self, index):
        self._layout.removeWidget(self._hClsWidgetList[index])
        self._hClsWidgetList[index].deleteLater()
        del self._hClsWidgetList[index]

    def replaceRow(self, to):
        self._layout.removeWidget(self._hClsWidgetList[2])
        self._layout.addWidget(to)
        self._hClsWidgetList[2] = to

    def current(self):
        ret = []
        for each in self._hClsWidgetList:
            ret.append(each.current())
        return ret

    def addCls(self):
        cls = self.sender()
        state, cls_name, img_path = cls.addCls()

        if state:
            temp = self.current()
            if temp[1] is not None:
                type1 = temp[1].text()
                state, res = self._handle.addCls(type1, cls_name, img_path)
                print(res)
                if state:
                    self.updateOneType2Data(type1, cls_name, res["pid"])
                    cls.addCol(cls_name)
                else:
                    WarningMessageBox("类添加失败, 服务器异常").exec()

    def onRmCls(self, clsName):
        cls = self.sender()
        temp = self.current()
        if temp[1] is not None:
            if self._hClsWidgetList[2].count() > 1:
                self.sg_onRmCls.emit([temp[1].text(), clsName, cls])
            else:
                WarningMessageBox("请先添加一个类别再删除，需最少保留一个分类").exec()

    def rmCls(self, type1, type2, cls):
        if type1 is not None:
            state, res = self._handle.rmCls(type1, type2)
            print(res)
            if state:
                self._rowDatamap.get(type1).remove(type2)
                cls.rmCls()
            else:
                WarningMessageBox("类添加失败, 服务器异常").exec()

    def _onSelected(self, text):
        if text in self._rowDatamap.keys():
            self.rmRow(2)
            self.addRow(list(self._rowDatamap[text]))
        ret = list()
        for each in self._hClsWidgetList:
            if each.isSelected():
               ret.append(each.currentChecked.text())
            else:
                return
        self.allSelected.emit(ret)

    def getType1Index(self, type1):
        try:
            return self._type1map[type1]
        except:
            return None

    def getType2Index(self, type2):
        try:
            return self._type2map[type2]
        except:
            return None

    def updateOneType2Data(self, goods_type1, goods_type2, pid):
        self._type2map[goods_type2] = pid
        self._rowDatamap[goods_type1].add(goods_type2)

    def getData(self, data):
        if data is not None:
            for each in data:
                self._type1map[each["goods_type1"]] = each["id"]
                self._type2map[each["goods_type2"]] = each["pid"]

            for each in self._type1map.keys():
                self._rowDatamap[each] = set()

            for each in data:
                self._rowDatamap[each["goods_type1"]].add(each["goods_type2"])

            reOrder = self._rowDatamap.get("其它")

            if reOrder is not None:
                del self._rowDatamap["其它"]
                self._rowDatamap["其它"] = reOrder

class shopWidget(QStackedWidget):
    def __init__(self, parent=None):
        super(shopWidget, self).__init__(parent)
        self._handle = goodsHandle()

        self._editWidget = goodsMessageEditWidget()
        self._glayout = QGridLayout()
        self._goodsList = list()
        self._mainWidget = QWidget()
        self._currentClass = None
        self._data = None
        # 初始化商品列表
        self._goodsScrollArea = QScrollArea()
        self._goodsWidget = QWidget(self._goodsScrollArea)
        self._goodsWidget.setProperty("class", "showItemWidget")
        # 添加按键
        self._addGoodsItemBtn = QPushButton()
        self._addGoodsItemBtn.clicked.connect(self._addGoodsItem)
        self._addGoodsItemBtn.setProperty("class", "addBtn")
        # sd = QGraphicsDropShadowEffect()
        # sd.setColor(Qt.gray)
        # sd.setBlurRadius(45)
        # self._addGoodsItemBtn.setGraphicsEffect(sd)
        # self._addGoodsItemBtn.setFixedSize(30, 30)

        #self.disPlayGoodsItem([])
        self._goodsScrollArea.setWidget(self._goodsWidget)
        self.setAttribute(Qt.WA_StyledBackground, True)
        self._goodsScrollArea.setProperty("class", "showItemWidget")
        self.addWidget(self._mainWidget)
        self.addWidget(self._editWidget)

        # 分类栏
        self._classifyWidget = classifyWidget(self)
        self._classifyWidget.allSelected.connect(self._classChange)
        self._classifyWidget.sg_onRmCls.connect(self._rmCls)

        # 上下架及页面控制
        self._editWidget.cancelBtnClicked.connect(self._onCancel)
        self._editWidget.goodsStatus.connect(self._onStatusChange)

        # 删除商品
        self._editWidget.goodsDelete.connect(self._onDelete)

        self._descLb = QLabel()
        self._descLb.setProperty("class", "pageDescLb")
        self._descLb.setText("商品上架管理")

        # 主布局
        self._mainLayout = QVBoxLayout()
        self._mainLayout.addWidget(self._descLb, 0, Qt.AlignCenter)
        self._mainLayout.addWidget(self._classifyWidget)
        self._mainLayout.addWidget(self._goodsScrollArea)
        self._mainWidget.setLayout(self._mainLayout)

        self.showMaximized()

    def init_goods_cls(self, data):
        self._classifyWidget.show_init(data)

    def disPlayGoodsItem(self, data, refresh=False, data_refresh=False):
        if refresh:
            for each in range(self._goodsList.__len__()):
                self._glayout.removeWidget(self._goodsList[each])
                self._goodsList[each].deleteLater()
            self._goodsList.clear()
        else:
            self._data = data

        isfirst = False

        if self._data is None:
            isfirst = True

        if data_refresh:
            self._data = data

        if not isfirst:
            for each in range(data.__len__()):
                self._goodsList.append(goodsItem())
                self._goodsList[each].updateData(data[each])
                self._goodsList[each].goodsItemClicked.connect(self._changeWidget)
            for each in range(self._goodsList.__len__()):
                self._glayout.addWidget(self._goodsList[each], each//4+1, each%4, 1, 1, Qt.AlignTop | Qt.AlignLeft)
            self._glayout.addWidget(self._addGoodsItemBtn, 0, 0, 1, 4, Qt.AlignRight | Qt.AlignTop)
            self._glayout.setSpacing(10)
            self._goodsWidget.resize(4 * 260, ((self._goodsList.__len__() - 1) // 4 + 1)
                                     * 320 + 57)
            self._goodsWidget.setLayout(self._glayout)

    def _reshow(self):
        self._glayout.addWidget(self._addGoodsItemBtn, 0, 0, 1, 4, Qt.AlignRight | Qt.AlignTop)
        for each in range(self._goodsList.__len__()):
            self._glayout.addWidget(self._goodsList[each], each//4+1, each%4, 1, 1, Qt.AlignTop | Qt.AlignLeft)
        self._goodsWidget.resize(4 * 260, ((self._goodsList.__len__() - 1) // 4 + 1)
                                 * 320 + self._addGoodsItemBtn.height())

    def _indexOfGoodsItem(self, item):
        for index in range(self._goodsList.__len__()):
            if id(item) == id(self._goodsList[index]):
                return index

        return None

    def _changeWidget(self, data):
        if self._currentClass is not None:
            self.sender().setDataIndex(self._data.index(data))
            self.setCurrentIndex(1)
            self._editWidget.setClass(self._currentClass)
            self._editWidget.updateData(copy.deepcopy(data))

    def _onCancel(self):
        self.setCurrentIndex(0)

    def _new_image_name(self):
        img_name = str(time.time()).replace('.', '') + '.jpg'
        return img_name

    def _get_imgs(self, img_list):
        ret = list()
        for each in img_list:
            if each.startswith("http"):
                try:
                    file = requests.get(each)
                    img = cv2.imdecode(np.fromstring(file.content, np.uint8), 1)
                    imgname = './temp/' + self._new_image_name()
                    ret.append(imgname)
                    cv2.imwrite(imgname, img)
                except Exception as e:
                    print(e)
                    return False, None
            elif each == "请点击插入图片":
                pass
            else:
                url = each.encode("utf-8")
                image_data = b64decode(url)
                img = cv2.imdecode(np.fromstring(image_data, np.uint8), 1)
                imgname = './temp/' + self._new_image_name()
                ret.append(imgname)
                cv2.imwrite(imgname, img)

        return True, ret

    def _get_goods_post_data(self, post_data):
        post_data["create_by"] = "yixianshenji"
        post_data["update_by"] = "yixianshenji"
        post_data["status"] = 0
        post_data["items"] = ""
        post_data["table"] = "pro_goods"
        post_data["goods_type1"] = int(post_data["goods_type1"])
        post_data["goods_type2"] = int(post_data["goods_type2"])
        state, ret = self._get_imgs(post_data["imagesSlider"])
        state1, ret1 = self._get_imgs(post_data["imageContent"])
        if state and state1 and ret.__len__() > 0 and ret1.__len__() > 0:
            post_data["imagesSlider"] = ret
            post_data["imageContent"] = ret1
            return True, post_data
        else:
            return False, None

    def _onStatusChange(self, status):
        self._editWidget.setSalesStatus(status)
        data = self._editWidget.getEditedData()
        post_data = copy.deepcopy(data)

        if status:
            state, post_data = self._get_goods_post_data(post_data)

            if state:
                state, res = self._handle.updateGoods(post_data)
                print(res)
                if state:
                    data["goods_id"] = res.get("goods_id")
                else:
                    WarningMessageBox("上架失败, 服务器异常").exec()
                    return
            else:
                WarningMessageBox("上架失败, 图片不能为空，或服务器异常").exec()
                return
        else:
            goods_id = post_data["goods_id"]
            state, res = self._handle.goods_sout_out(goods_id)
            print(res)
            if not state:
                WarningMessageBox(" 下架失败, 服务器异常").exec()
                return

        shutil.rmtree('./temp')
        os.mkdir('./temp')
        ret = self._editWidget.updateGoodsItem()
        if ret is not None:
            self._data.append(data)
            ret.goodsItemClicked.connect(self._changeWidget)
            self._goodsList.append(ret)
            self._glayout.addWidget(ret, (self._goodsList.__len__()-1)//4+1, (self._goodsList.__len__()-1)%4,
                                    1, 1, Qt.AlignTop | Qt.AlignLeft)
            self._goodsWidget.resize(self._goodsWidget.width(), ((self._goodsList.__len__()-1)//4+1)
                                     * (ret.height()+20)+self._addGoodsItemBtn.height())
        else:
            item = self._editWidget.currentEditItem()
            self._data[item.dataIndex()] = data

        self.setCurrentIndex(0)

    def _addGoodsItem(self):
        if self._currentClass is not None:
            self._editWidget.setClass(self._currentClass)
            self.setCurrentIndex(1)
            self._editWidget.updateData(copy.deepcopy(initGoodsItemData), True)

    def _onDelete(self, item):
        if item[0] is None:
            self.setCurrentIndex(0)
        else:
            item_data = item[0].data()
            goods_id = item_data["goods_id"]
            state, res = self._handle.goods_del(goods_id)
            if not state:
                WarningMessageBox("删除失败, 服务器异常").exec()
                return

            self.setCurrentIndex(0)
            # 去除界面布局
            for each in self._goodsList:
                self._glayout.removeWidget(each)
            # 删除对应商品
            index = item[0].dataIndex()

            del self._data[index]
            goodsindex = self._goodsList.index(item[0])
            item[0].setParent(None)
            item[0].deleteLater()
            del self._goodsList[goodsindex]
            # 重新布局
            self._reshow()

    def _classChange(self, data):
        if data[0] == "普通":
            buy_type = 1
        elif data[0] == "拼团":
            buy_type = 2
        else:
            buy_type = 3
        goods_type1 = self._classifyWidget.getType1Index(data[1])
        goods_type2 = self._classifyWidget.getType2Index(data[2])
        self._currentClass = dict()
        self._currentClass[data[0]] = buy_type
        self._currentClass[data[1]] = goods_type1
        self._currentClass[data[2]] = goods_type2
        temp = list()
        for each in self._data:
            if each["goods_type1"] == goods_type1 and each["goods_type2"] == goods_type2 and each["buy_type"] == buy_type:
                temp.append(each)
        self.disPlayGoodsItem(temp, refresh=True)

    def _rmCls(self, clsMsg):
        hasGoods = False
        idtype1 = self._classifyWidget.getType1Index(clsMsg[0])
        idtype2 = self._classifyWidget.getType2Index(clsMsg[1])

        if idtype1 is not None and idtype2 is not None:
            for each in self._data:
                if each["goods_type1"] == idtype1 and each["goods_type2"] == idtype2:
                    hasGoods = True
                    break

            if hasGoods:
                WarningMessageBox("请先删除普通、团购、分销下的此分类商品").exec()
                return
            else:
                self._classifyWidget.rmCls(clsMsg[0], clsMsg[1], clsMsg[2])


def main():
    app = QApplication(sys.argv)

    ui = shopWidget()

    ui.show()

    sys.exit(app.exec())

if __name__ == "__main__":
    main()
